




using System;
using System.Data;using THSERP.BusinessEntities;using THSERP.BaseProvider;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
using System.Windows.Forms;
using THSLib;using THSERP.BaseProvider;

namespace THSERP.Modules.Shipment
{
    public class ShipmentEntities : ERPModuleEntities
    {
        #region Declare Constant
        public readonly static String strICShipmentsObjectName = "ICShipments";

        public readonly static String strICShipmentItemsObjectName = "ICShipmentItems";
        #endregion
        
        #region Declare all entities variables
        private ICShipmentsInfo _ICShipmentsObject;
        private ICShipmentItemsInfo _ICShipmentItemsObject;
 
        public THSItemsEntityList<ShipmentItemsEntity> lstICShipmentItems;
        public THSList<ICShipmentSaleOrdersInfo> lstICShipmentSaleOrdersInfo;
        #endregion

        #region Public Properties
        public ICShipmentsInfo ICShipmentsObject
        {
            get
            {
                return _ICShipmentsObject;
            }
            set
            {
                _ICShipmentsObject = value;
            }
        }
        public ICShipmentItemsInfo ICShipmentItemsObject
        {
            get
            {
                return _ICShipmentItemsObject;
            }
            set
            {
                _ICShipmentItemsObject = value;
            }
        }

        public THSItemsEntityList<ShipmentItemsEntity> ICShipmentItemsList
        {
            get
            {
                return lstICShipmentItems;
            }
            set
            {
                lstICShipmentItems = value;
            }
        }

        public THSList<ICShipmentSaleOrdersInfo> ICShipmentSaleOrdersList
        {
            get
            {
                return lstICShipmentSaleOrdersInfo;
            }
            set
            {
                lstICShipmentSaleOrdersInfo = value;
            }
        }
       
        #endregion

        #region Constructor
        public ShipmentEntities()
            : base()
        {
            _ICShipmentsObject = new ICShipmentsInfo();

            _ICShipmentItemsObject = new ICShipmentItemsInfo();

            lstICShipmentItems = new THSItemsEntityList<ShipmentItemsEntity>();
            lstICShipmentSaleOrdersInfo = new THSList<ICShipmentSaleOrdersInfo>();
        }

        #endregion

        #region Init Main Object,Module Objects functions
        public override void InitMainObject()
        {

            MainObject = ICShipmentsObject;
        }

        public override void InitModuleObjects()
        {
            ModuleObjects.Add("ICShipmentItems", ICShipmentItemsObject);
        }

        public override void InitModuleObjectList()
        {            
            lstICShipmentItems = new THSItemsEntityList<ShipmentItemsEntity>();
            lstICShipmentItems.InitTHSList(this, 
                                            THSUtil.GetTableNameFromBusinessObjectType(typeof(ICShipmentsInfo)),
                                            THSUtil.GetTableNameFromBusinessObjectType(typeof(ICShipmentItemsInfo)));
        }

        public override void InitGridControlInTHSList()
        {
            lstICShipmentItems.InitTHSListGridControl();
        }

        public override void SetDefaultModuleObjectsList()
        {
            try
            {
                lstICShipmentItems.SetDefaultListAndRefreshGridControl();
                lstICShipmentSaleOrdersInfo.Clear();

            }
            catch (Exception)
            {
                return;
            }
        }

        #endregion

        #region Invalidate Module Objects functions


        public override void InvalidateModuleObjects(int iObjectID)
        {
            ICShipmentItemsList.Invalidate(iObjectID);
        }


        #endregion

        #region Save Module Objects functions

        public override void SaveModuleObjects()
        {
            if(Module!=null)
            {
                if (Module.Toolbar.IsEditAction())
                {
                    THSItemsEntityList<ShipmentItemsEntity> lstOldShipmentItemsEntity = new THSItemsEntityList<ShipmentItemsEntity>();
                    lstOldShipmentItemsEntity.InitTHSList(this, 
                                                           THSUtil.GetTableNameFromBusinessObjectType(typeof(ICShipmentsInfo)),
                                                           THSUtil.GetTableNameFromBusinessObjectType(typeof(ICShipmentItemsInfo)));
                    lstOldShipmentItemsEntity.InvalidateAndNotUpdateModuleObjects(Module.Toolbar.CurrentObjectID);
                    lstOldShipmentItemsEntity.UpdateInventory(BusinessObject.DeletedAAStatus);
                }
            }

            SaveMainObjectRelations();

            ICShipmentItemsList.SaveItemObjects(true);

            UpdateSaleOrderStatus();

            lstICShipmentItems.UpdateInventory(BusinessObject.DefaultAAStatus);
        }

        public void UpdateSaleOrderStatus()
        {
            ARSaleOrdersController objARSaleOrdersController = new ARSaleOrdersController();
            foreach (ICShipmentSaleOrdersInfo objICShipmentSaleOrdersInfo in ICShipmentSaleOrdersList)
            {
                int iARSaleOrderID = objICShipmentSaleOrdersInfo.FK_ARSaleOrderID;
                ARSaleOrdersInfo objARSaleOrdersInfo = (ARSaleOrdersInfo)objARSaleOrdersController.GetObjectByID(iARSaleOrderID);
                if (SaleOrderIsComplete(iARSaleOrderID))
                {
                    objARSaleOrdersInfo.ARSaleOrderStatus = SaleOrder.SaleOrderModule.cstSaleOrderStatusComplete;
                }
                else
                {
                    objARSaleOrdersInfo.ARSaleOrderStatus = SaleOrder.SaleOrderModule.cstSaleOrderStatusIncomplete;
                }

                objARSaleOrdersController.UpdateObject(objARSaleOrdersInfo);
            }
        }


        public bool SaleOrderIsComplete(int iARSaleOrderID)
        {
            ARSaleOrderItemsController objARSaleOrderItemsController = new ARSaleOrderItemsController();
            ICShipmentItemsController objICShipmentItemsController = new ICShipmentItemsController();
            DataSet dsARSaleOrderItems = objARSaleOrderItemsController.GetAllDataByForeignColumn("FK_ARSaleOrderID", iARSaleOrderID);
            foreach (DataRow rowARSaleOrderItem in dsARSaleOrderItems.Tables[0].Rows)
            {
                ARSaleOrderItemsInfo objARSaleOrderItemsInfo = (ARSaleOrderItemsInfo)objARSaleOrderItemsController.GetObjectFromDataRow(rowARSaleOrderItem);
                double dbTotalShippedQty = objICShipmentItemsController.GetTotalShippedQuantityOfSaleOrderItem(objARSaleOrderItemsInfo.ARSaleOrderItemID);
                if (dbTotalShippedQty < objARSaleOrderItemsInfo.ARSaleOrderItemProductQty)
                    return false;
            }
            return true;
        }

        public override void SaveMainObjectRelations()
        {
            
            ICShipmentSaleOrdersController objICShipmentSaleOrdersController = new ICShipmentSaleOrdersController();

            String strMainTableName = THSUtil.GetTableNameFromBusinessObject(MainObject);
            String strMainTablePrimaryKey = strMainTableName.Substring(0, strMainTableName.Length - 1) + "ID";
            int iMainObjectID = Convert.ToInt32(THSDbUtil.GetPropertyValue(MainObject, strMainTablePrimaryKey));

            //Save all ICShipmentSaleOrders
            if (iMainObjectID > 0)
            {
                foreach (ICShipmentSaleOrdersInfo objICShipmentSaleOrdersInfo in lstICShipmentSaleOrdersInfo)
                {
                    if (objICShipmentSaleOrdersInfo.FK_ICShipmentID > 0)
                    {
                        objICShipmentSaleOrdersController.UpdateObject(objICShipmentSaleOrdersInfo);
                    }
                    else
                    {
                        objICShipmentSaleOrdersInfo.FK_ICShipmentID = iMainObjectID;
                        objICShipmentSaleOrdersController.CreateObject(objICShipmentSaleOrdersInfo);
                    }
                }
            }
        }

        public override void SaveObjectItemRelations(ERPModuleItemsEntity entItems)
        {
            ICShipmentItemSaleOrderItemsController objICShipmentItemSaleOrderItemsController = new ICShipmentItemSaleOrderItemsController();
            ShipmentItemsEntity entShipmentItems= (ShipmentItemsEntity)entItems;

            //Save all ICShipmentItemSaleOrderItems
            foreach (ICShipmentItemSaleOrderItemsInfo objICShipmentItemSaleOrderItemsInfo in entShipmentItems.ICShipmentItemSaleOrderItemsList)
            {
                if (objICShipmentItemSaleOrderItemsInfo.FK_ICShipmentItemID > 0)
                {
                    objICShipmentItemSaleOrderItemsController.UpdateObject(objICShipmentItemSaleOrderItemsInfo);
                }
                else
                {
                    objICShipmentItemSaleOrderItemsInfo.FK_ICShipmentItemID = entShipmentItems.ICShipmentItemID;
                    objICShipmentItemSaleOrderItemsController.CreateObject(objICShipmentItemSaleOrderItemsInfo);
                }
            }
        }

        #endregion

        #region Delete Shipment function
        public override void Delete(int iObjectID)
        {
            THSItemsEntityList<ShipmentItemsEntity> lstOldShipmentItemsEntity = new THSItemsEntityList<ShipmentItemsEntity>();
            lstOldShipmentItemsEntity.InitTHSList(this, 
                                                   THSUtil.GetTableNameFromBusinessObjectType(typeof(ICShipmentsInfo)),
                                                   THSUtil.GetTableNameFromBusinessObjectType(typeof(ICShipmentItemsInfo)));
            lstOldShipmentItemsEntity.InvalidateAndNotUpdateModuleObjects(Module.Toolbar.CurrentObjectID);

            ICShipmentItemsController objICShipmentItemsController = new ICShipmentItemsController();
            objICShipmentItemsController.DeleteByForeignColumn("FK_ICShipmentID", iObjectID);

            base.Delete(iObjectID);

            UpdateSaleOrderStatus();

            lstOldShipmentItemsEntity.UpdateInventory(BusinessObject.DeletedAAStatus);
        }
        #endregion

        public override void SetValuesAfterValidateProduct(int iICProductID)
        {
            //base.SetDefaultValueFromProduct(iICProductID);
            ICShipmentItemsList.SetDefaultValuesFromProduct(iICProductID);
        }

        public override void CalculateTotalInformation(ref double dbTotalPrice, ref double dbTotalItemDiscountAmount, ref double dbDiscountAmount, ref double dbTotalTaxAmount, ref double dbTotalBuyingPrice, ref double dbTotalItemNetAmount, ref double dbTotalNetAmount, ref double dbTotalGrossAmount, ref double dbMarginPercent)
        {                       
            foreach (ShipmentItemsEntity entShipmentsItem in ICShipmentItemsList)
            {
                ICShipmentItemsInfo objICShipmentItemsInfo = (ICShipmentItemsInfo)entShipmentsItem.SetToBusinessObject(strICShipmentItemsObjectName);
                //Calculate item total price
                dbTotalPrice += THSUtil.Round(objICShipmentItemsInfo.ICShipmentItemPrice,THSApp.PriceDecimal);

                //Calculate total item discount amount
                dbTotalItemDiscountAmount += THSUtil.Round(objICShipmentItemsInfo.ICShipmentItemPrice * objICShipmentItemsInfo.ICShipmentItemProductDiscount / 100,THSApp.PriceDecimal);

                //Calculate total item tax amount
                dbTotalTaxAmount += THSUtil.Round(objICShipmentItemsInfo.ICShipmentItemPrice * objICShipmentItemsInfo.ICShipmentItemProductTaxPercent / 100,THSApp.PriceDecimal);

                //Calculate buying price
                int iICProductID = objICShipmentItemsInfo.FK_ICProductID;
                ICProductsInfo objICProductsInfo = (ICProductsInfo)new ICProductsController().GetObjectByID(iICProductID);
                if (objICProductsInfo != null)
                {
                    dbTotalBuyingPrice += objICProductsInfo.ICProductSupplierPrice * entShipmentsItem.ICShipmentItemProductQty;
                }
            }

            //Calculate dbTotalItemNetAmount(ZSum)
            dbTotalItemNetAmount = dbTotalPrice - dbTotalItemDiscountAmount;

            //Calculate dbSaleOrderDiscountAmount
            ICShipmentsInfo objICShipmentsInfo = (ICShipmentsInfo)MainObject;
            if (objICShipmentsInfo.ICShipmentIsDiscountPercentCheck)
                dbDiscountAmount = dbTotalItemNetAmount * objICShipmentsInfo.ICShipmentDiscountPerCent / 100;
            else
                dbDiscountAmount = objICShipmentsInfo.ICShipmentDiscountFix;

            //Calculate dbTotalNetAmount
            dbTotalNetAmount = dbTotalItemNetAmount - dbDiscountAmount;

            //Calculate Total Gross Amount
            dbTotalGrossAmount = dbTotalNetAmount + dbTotalTaxAmount;

            //Calculate Profit percent
            if (dbTotalPrice > 0)
                dbMarginPercent = (dbTotalItemNetAmount - dbTotalBuyingPrice) * 100 / dbTotalItemNetAmount;

        }

        public override void UpdateInventory(ERPModuleItemsEntity entItems, string strUpdateStatus)
        {
            DataSet ds = new DataSet();            
            

            String strMainTableName = THSUtil.GetTableNameFromBusinessObject(MainObject);
            String strItemTableName = strMainTableName.Substring(0, strMainTableName.Length - 1) + "Items";
            BusinessObject objItemsInfo = ((ERPModuleItemsEntity)entItems).SetToBusinessObject(strItemTableName);
            String strItemProductTypeColumnName = strItemTableName.Substring(0, strItemTableName.Length - 1) + "ProductType";
            String strItemProductType = THSDbUtil.GetPropertyValue(objItemsInfo, strItemProductTypeColumnName).ToString();
            String strShipmentType = (MainObject as ICShipmentsInfo).ICShipmentTypeCombo;

            String strItemProductSerialNoColumnName = strItemTableName.Substring(0, strItemTableName.Length - 1) + "ProductSerialNo";
            String strItemProductSerialNo = THSDbUtil.GetPropertyValue(objItemsInfo, strItemProductSerialNoColumnName).ToString();

            
            //not update inventory if product is Service or Comment
            if (!strItemProductType.Contains(Product.ProductModule.cstProductTypeService) && !strItemProductType.Contains(Product.ProductModule.cstProductTypeComment))
            {
                int iICProductID = Convert.ToInt32(THSDbUtil.GetPropertyValue(objItemsInfo, "FK_ICProductID"));
                int iICStockID = Convert.ToInt32(THSDbUtil.GetPropertyValue(objItemsInfo, "FK_ICStockID"));
                int iICStockSlotID = Convert.ToInt32(THSDbUtil.GetPropertyValue(objItemsInfo, "FK_ICStockSlotID"));

                int iSaleOrderICInventoryStockID=0;
                int iSaleOrderICInventoryStockSlotID=0;

                String strItemProductQtyColumnName = strItemTableName.Substring(0, strItemTableName.Length - 1) + "ProductQty";

                double dbItemProductQty = Convert.ToDouble(THSDbUtil.GetPropertyValue(objItemsInfo, strItemProductQtyColumnName));

                String strItemStatus = THSDbUtil.GetPropertyValue(objItemsInfo, "AAStatus").ToString();

                if (strUpdateStatus == BusinessObject.DefaultAAStatus)
                {
                    //Update Inventory Stock
                    if (strItemStatus == BusinessObject.DefaultAAStatus)
                    {
                        int iICInventoryStockID = TransactionUtil.UpdateInventoryStock(
                                                    iICProductID, iICStockID,
                                                    dbItemProductQty,
                                                    TransactionUtil.cstInventoryShipment);
                        if (strShipmentType.Equals(ShipmentModule.cstShipmentTypeFromSaleOrder))
                        {
                            iSaleOrderICInventoryStockID = TransactionUtil.UpdateInventoryStock(
                                                                iICProductID, iICStockID,
                                                                -dbItemProductQty,
                                                                TransactionUtil.cstInventorySaleOrder);
                        }

                        //Update Inventory Stock Slot
                        if (iICInventoryStockID > 0)
                        {

                            int iICInventoryStockSlotID = TransactionUtil.UpdateInventoryStockSlot(
                                                            iICInventoryStockID, iICProductID,
                                                            iICStockSlotID,
                                                            dbItemProductQty,
                                                            TransactionUtil.cstInventoryShipment);

                            int iICInventoryStockSerieID = TransactionUtil.UpdateInventoryStockSerials(
                                iICInventoryStockID, iICProductID,
                                iICStockID, strItemProductSerialNo,
                                dbItemProductQty,
                                TransactionUtil.cstInventoryShipment);

                            if (iSaleOrderICInventoryStockID > 0)
                            {
                                iSaleOrderICInventoryStockSlotID = TransactionUtil.UpdateInventoryStockSlot(
                                                                    iSaleOrderICInventoryStockID,
                                                                    iICProductID, iICStockSlotID,
                                                                    -dbItemProductQty,
                                                                    TransactionUtil.cstInventorySaleOrder);
                            }
                        }
                    }
                }
                else if (strUpdateStatus == BusinessObject.DeletedAAStatus)
                {
                    //Update Inventory Stock
                    int iICInventoryStockID = TransactionUtil.UpdateInventoryStock(
                                                iICProductID, iICStockID,
                                                -dbItemProductQty,
                                                TransactionUtil.cstInventoryShipment);
                    iSaleOrderICInventoryStockID = TransactionUtil.UpdateInventoryStock(
                                                  iICProductID, iICStockID,
                                                  dbItemProductQty,
                                                  TransactionUtil.cstInventorySaleOrder);

                    //Update Inventory Stock Slot
                    if (iICInventoryStockID > 0)
                    {
                        int iICInventoryStockSlotID = TransactionUtil.UpdateInventoryStockSlot(
                                                        iICInventoryStockID, iICProductID,
                                                        iICStockSlotID,
                                                        -dbItemProductQty,
                                                        TransactionUtil.cstInventoryShipment);
                        int iICInventoryStockSerieID = TransactionUtil.UpdateInventoryStockSerials(
                                                              iICInventoryStockID, iICProductID,
                                                              iICStockID, strItemProductSerialNo,
                                                              -dbItemProductQty,
                                                              TransactionUtil.cstInventoryShipment);

                        if (iSaleOrderICInventoryStockID > 0)
                        {
                            iSaleOrderICInventoryStockSlotID = TransactionUtil.UpdateInventoryStockSlot(
                                                             iSaleOrderICInventoryStockID,
                                                             iICProductID, iICStockSlotID,
                                                             dbItemProductQty, TransactionUtil.cstInventorySaleOrder);
                        }
                    }
                }

            }            
        }

        #region Generate Entity From Related Entity functions
        public override void  GenerateModuleItemsList(BusinessObject objRelatedMainObjectInfo)
        {

            ARSaleOrderItemsController objARSaleOrderItemsController = new ARSaleOrderItemsController();
            ICShipmentItemsController objICShipmentItemsController = new ICShipmentItemsController();
            int iARSaleOrderID = ((ARSaleOrdersInfo)objRelatedMainObjectInfo).ARSaleOrderID;

            DataSet dsSaleOrderItems = objARSaleOrderItemsController.GetAllDataByForeignColumn("FK_ARSaleOrderID", iARSaleOrderID);
            if (dsSaleOrderItems.Tables.Count > 0)
            {
                foreach (DataRow rowSaleOrderItem in dsSaleOrderItems.Tables[0].Rows)
                {
                    ARSaleOrderItemsInfo objARSaleOrderItemsInfo = (ARSaleOrderItemsInfo)objARSaleOrderItemsController.GetObjectFromDataRow(rowSaleOrderItem);
                    if (objARSaleOrderItemsInfo != null)
                    {
                        //First Add ICShipmentItems when total shipped quantity is less than SaleOrder Item Product Quantitys
                        double dbTotalShippedQuantity = objICShipmentItemsController.GetTotalShippedQuantityOfSaleOrderItem(objARSaleOrderItemsInfo.ARSaleOrderItemID);
                        if (dbTotalShippedQuantity < objARSaleOrderItemsInfo.ARSaleOrderItemProductQty)
                        {
                            //ShipmentItemsEntity entShipmentItems = GenerateICShipmentItemFromARSaleOrderItem(objARSaleOrderItemsInfo, dbTotalShippedQuantity);                            
                            ShipmentItemsEntity entShipmentItems = (ShipmentItemsEntity)GenerateERPModuleItemsEntity(objARSaleOrderItemsInfo, dbTotalShippedQuantity);


                            entShipmentItems.Position = ICShipmentItemsList.Count;

                            ICShipmentItemsList.Add(entShipmentItems);
                        }
                    }
                }
            }

            ICShipmentItemsList.GridControl.RefreshDataSource();
        }


        public override void AddItemsRelations(ERPModuleItemsEntity entModuleItems, BusinessObject objRelatedModuleItemsInfo)        
        {
            
            String strRelatedModuleItemTableName = THSUtil.GetTableNameFromBusinessObject(objRelatedModuleItemsInfo);
            String strRelatedModuleItemTablePrimaryColumn = THSDbUtil.GetTablePrimaryColumn(strRelatedModuleItemTableName);
            int iRelatedModuleItemID = Convert.ToInt32(THSDbUtil.GetPropertyValue(objRelatedModuleItemsInfo, strRelatedModuleItemTablePrimaryColumn));

            ICShipmentItemSaleOrderItemsInfo objICShipmentItemSaleOrderItemsInfo = new ICShipmentItemSaleOrderItemsInfo();
            objICShipmentItemSaleOrderItemsInfo.FK_ARSaleOrderItemID = iRelatedModuleItemID;
            objICShipmentItemSaleOrderItemsInfo.Position = ((ShipmentItemsEntity)entModuleItems).ICShipmentItemSaleOrderItemsList.Count;
            ((ShipmentItemsEntity)entModuleItems).ICShipmentItemSaleOrderItemsList.Add(objICShipmentItemSaleOrderItemsInfo);
        }
        #endregion
    }
}
